package main

import (
	"flag"
	"fmt"
	"io"
	"os"
)

const command = "rm"

var ignErr = flag.Bool("f", false, "ignore files that can't be removed")
var recurse = flag.Bool("r", false, "remove recursively")
var exitCode = 0

func usage() {
	fmt.Fprint(os.Stderr, "usage: ", command, " [-f] [-r] file ...\n")
	os.Exit(2)
}

func printError(arg string, err error) {

	if !*ignErr {
		fmt.Fprint(os.Stderr, command, ": ", err.Error(), "\n")
		exitCode = 1
	}
}

func main() {
	flag.Usage = usage
	flag.Parse()
	for _, arg := range flag.Args() {
		if *recurse {
			rmAll(arg)
		} else {
			err := os.Remove(arg)
			if err != nil {
				printError(arg, err)
			}
		}
	}
	os.Exit(exitCode)
}

func rmAll(path string) {

	// Simple case: if Remove works, we're done.
	err := os.Remove(path)
	if err == nil {
		return
	}
	if os.IsNotExist(err) {
		printError(path, err)
		return
	}
	// Otherwise, is this a directory we need to recurse into?
	dir, serr := os.Lstat(path)
	if serr != nil {
		printError(path, serr)
		return
	}
	if !dir.IsDir() {
		// Not a directory; print the error from Remove
		printError(path, err)
		return
	}

	// Directory.
	fd, err := os.Open(path)
	if err != nil {
		printError(path, err)
		return
	}

	// Remove contents
	for {
		names, err := fd.Readdirnames(100)
		for _, name := range names {
			rmAll(path + string(os.PathSeparator) + name)
		}
		if err == io.EOF || len(names) == 0 {
			break
		}
	}
	// Close directory, because windows won't remove opened directory.
	fd.Close()

	// Remove directory.
	err = os.Remove(path)
	if err != nil {
		printError(path, err)
	}
}
